package com.zxl.openapi.filter;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
import com.zxl.openapi.bean.MQLogBean;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.net.InetAddress;
import java.net.UnknownHostException;

import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.POST_TYPE;

@Component
public class LogFilter extends ZuulFilter {

    //消息模板对象
    @Autowired
    private AmqpTemplate template;

    @Autowired
    private ObjectMapper objectMapper;


    @Override
    public String filterType() {
        //后置通知，拥有请求在结束后进行处理
        return POST_TYPE;

    }

    @Override
    public int filterOrder() {

        return 0;

    }

    @Override
    public boolean shouldFilter() {
        //无论如何都开收集日志，所以这个为true 无论什么时候都是开启的
        return true;

    }

    @Override
    public Object run() throws ZuulException {
        RequestContext currentContext = RequestContext.getCurrentContext();
        //获取当前时间
        long currentTimeMillis = System.currentTimeMillis();
        //获取请求开始的时间
        long receiveTime = (long) currentContext.get("receiveTime");

        HttpServletRequest request = currentContext.getRequest();
//        获取请求的参数
//        Map<String, String[]> parameterMap = request.getParameterMap();
        //查询网页地址栏所有的参数
        String queryString = request.getQueryString();
        //获取请求的IP地址
        String remoteAddr = request.getRemoteAddr();
        //获取本地IP地址
        String serverIp = getLocalIp();
        //获得时间差
        long totalTime = currentTimeMillis - receiveTime;

        String appkey = request.getParameter("appkey");

        String apiName = request.getParameter("method");

        MQLogBean mqLogBean = new MQLogBean();

        mqLogBean.setApiName(apiName);

        mqLogBean.setAppkey(appkey);

        mqLogBean.setReceiveTime(receiveTime);

        mqLogBean.setRemoteIp(remoteAddr);

        mqLogBean.setRepTime(currentTimeMillis);

        mqLogBean.setServerIp(serverIp);

        mqLogBean.setTotalRepTime(totalTime);

        mqLogBean.setRequestContent(queryString);
        //发送消息  直接发送到队列而不是交换机--> 只有一个地方写日志 不需要很多地方接受
        //消费者是一个集群，只要任何一个节点收到数据都可以写入日志，防止重复操作
        //可以发送java对象，但是做好不要，因为发送对象需要序列化和反序列化，因为默认情况下序列化是JAVA自带的，
        try {

            String logJson = objectMapper.writeValueAsString(mqLogBean);

            template.convertAndSend("suibianbigemingzi",logJson);

        } catch (JsonProcessingException e) {

            e.printStackTrace();

        }


        return null;

    }

    public String getLocalIp(){

        InetAddress address = null;

        try {

            address=InetAddress.getLocalHost();

            return address.getHostAddress();

        } catch (UnknownHostException e) {

            e.printStackTrace();

        }

        return "0.0.0.0";
    }

}
